﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Web.Mvc;
using System.Web.Script.Serialization;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using SweetSurvey.Controllers;
using SweetSurvey.Models;
using SweetSurvey.Models.Repositories;

namespace SweetSurvey.Tests.ControllerTests
{
    [TestClass]
    public class AdministratorControllerTest : ControllerTestBase
    {
        [TestMethod]
        public void SurveysTest()
        {
            // variables
            var count = 10;

            // prepare
            var mockSurveyRepository = new Mock<ISurveyRepository>(MockBehavior.Strict);
            mockSurveyRepository.Setup(r => r.GetAllSurveys()).Returns(() =>
            {
                var list = new List<Survey>();
                for (var i = 0; i < count; i++) { list.Add(new Survey()); }
                return list.AsQueryable<Survey>();
            });
            var controller = new AdministratorController(mockSurveyRepository.Object, null);

            // act
            var result = controller.Surveys();

            // assert
            mockSurveyRepository.VerifyAll();
            Assert.IsInstanceOfType(result, typeof(ViewResult));
            var model = ((ViewResult)result).Model;
            Assert.IsInstanceOfType(model, typeof(IQueryable<Survey>));
            Assert.AreEqual<int>(count, ((IQueryable<Survey>)model).Count());
        }

        [TestMethod]
        public void DeleteSurveysTest()
        {
            // variables
            var count = 10;
            Expression<Action<ISurveyRepository>> deleteExpression = (r => r.Delete(It.IsAny<string>()));
            var surveyIds = new List<string>();
            for (var i = 0; i < count; i++) { surveyIds.Add(string.Empty); }

            // prepare
            var mockSurveyRepository = new Mock<ISurveyRepository>(MockBehavior.Strict);
            mockSurveyRepository.Setup(deleteExpression);
            var controller = new AdministratorController(mockSurveyRepository.Object, null);

            // act
            var result = controller.DeleteSurveys((new JavaScriptSerializer()).Serialize(surveyIds));

            // assert
            mockSurveyRepository.Verify(deleteExpression, Times.Exactly(count));
            Assert.IsInstanceOfType(result, typeof(ContentResult));
            Assert.AreEqual<string>("success", ((ContentResult)result).Content);
        }

        [TestMethod]
        public void ParticipatorsTest()
        {
            // variables
            Expression<Func<IParticipatorRepository, IQueryable<ParticipatorModel>>> expression = (r => r.GetAllParticipators());

            // prepare
            var mockParticipatorRepository = new Mock<IParticipatorRepository>(MockBehavior.Strict);
            mockParticipatorRepository.Setup(expression).Returns((new List<ParticipatorModel>()).AsQueryable<ParticipatorModel>());
            var controller = new AdministratorController(null, mockParticipatorRepository.Object);

            // act
            var result = controller.Participators();

            // assert
            mockParticipatorRepository.Verify(expression, Times.Once());
            Assert.IsInstanceOfType(result, typeof(ViewResult));
            var model = ((ViewResult)result).Model;
            Assert.IsInstanceOfType(model, typeof(IQueryable<ParticipatorModel>));
        }
    }
}
